<template>
  <div id="hy-table" class="rounded bg-white">
    <slot name="tableTitle"> </slot>

    <el-table
      ref="tableRef"
      style="width: 100%"
      v-bind="childrenProps"
      highlight-current-row
      :height="height"
      :data="listData"
      :cell-style="() => cellStyle"
      :header-cell-style="() => headerCellStyle"
      @selection-change="handleSelectionChange"
      :row-key="getRowKeys"
      :tree-props="treeProps"
    >
      <el-table-column
        v-if="selectColumnType === SelectType.RADIO"
        align="center"
        width="60"
        label="选择"
      >
        <template #default="scope">
          <el-radio
            class="radio"
            v-model="selectedData"
            :label="scope.row[props.selectKey]"
          >
            {{ scope.row[props.selectKey] }}
          </el-radio>
        </template>
      </el-table-column>

      <el-table-column
        v-if="selectColumnType === SelectType.CHECKBOX"
        type="selection"
        align="center"
        width="60"
        :reserve-selection="true"
        :selectable="(row: any) => !disableIds.includes(row[selectKey])"
      ></el-table-column>

      <el-table-column
        v-if="showIndexColumn"
        type="index"
        label="序号"
        align="center"
        width="80"
      ></el-table-column>

      <el-table-column
        v-bind="propItem"
        v-for="propItem in propList"
        :label="propItem.label"
        :key="propItem.prop"
        :header-align="propItem.headerAlign"
        :align="propItem.align"
        :width="propItem.width"
        show-overflow-tooltip
      >
        <template v-if="propItem.headerSlotName" #header="column">
          <slot :name="propItem.headerSlotName" v-bind="column"> </slot>
        </template>

        <template #default="scope">
          <slot :name="propItem.slotName" v-bind="scope.row">
            {{ scope.row[propItem.prop] || '--' }}
          </slot>
        </template>
      </el-table-column>
    </el-table>

    <div class="footer flex justify-center pb-8 pt-8" v-if="showFooter">
      <slot name="footer">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :hide-on-single-page="true"
          :current-page="searchForm.page"
          :page-size="searchForm.size"
          :page-sizes="[10, 20, 30]"
          :layout="paginationLayout"
          :total="listCount"
        >
        </el-pagination>
      </slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { TableInstance } from 'element-plus'
import { SelectType } from '@/common/hy-table/typing'
import { tableSearch } from '@/service/api/sys/table/table'

const emit = defineEmits(['getTotal', 'selectionChange'])

const tableRef = ref<TableInstance>()
const searchForm = ref({
  size: 10,
  page: 1
})
const listData = ref<any[]>([])
const listCount = ref(0)
const selectedData = ref<any>([])

const getRowKeys = computed(() => (row: any) => {
  return row[props.selectKey]
})

const props = defineProps({
  height: {
    type: [String, Number]
  },

  propList: {
    type: Array as any,
    required: true
  },

  showIndexColumn: {
    type: Boolean,
    default: false
  },

  selectColumnType: {
    type: Number,
    default: SelectType.CHECKBOX
  },

  childrenProps: {
    type: Object,
    default: () => ({})
  },

  showFooter: {
    type: Boolean,
    default: true
  },

  reqUrl: {
    type: String,
    default: ''
  },

  cellStyle: {
    type: Function as any
  },

  headerCellStyle: {
    type: Function as any
  },

  disableIds: {
    type: Array,
    default() {
      return []
    }
  },

  propsSearchForm: {
    type: Object
  },

  selectKey: {
    type: String,
    default() {
      return 'id'
    }
  },

  paginationLayout: {
    type: String,
    default() {
      return 'total, sizes, prev, pager, next, jumper'
    }
  },

  treeProps: {
    type: Object,
    default() {
      return {}
    }
  }
})

onMounted(() => getListData())

// 获取列表数据
const getListData = async (queryInfo?: any) => {
  const form = {
    ...props?.propsSearchForm,
    ...searchForm.value,
    ...queryInfo
  }

  const urlName = props.reqUrl.replace(/^\.\/(.*)\.\w+$/, '$1')
  const splitNames = urlName.split('/')
  const name = splitNames[splitNames.length - 1]

  if (name === 'findAll') {
    const { data } = await tableSearch(props.reqUrl, form)
    listData.value = data
    return
  }

  if (name === 'page') {
    const { data, code } = await tableSearch(props.reqUrl, form)
    if (code !== 200) return
    const { total, records } = data
    listCount.value = total
    listData.value = records
    emit('getTotal', total)
  }
}

// 复选框
const handleSelectionChange = (rows: any) => {
  selectedData.value = []

  if (rows) {
    rows.forEach((row: any) => {
      if (row) {
        selectedData.value.push(row[props.selectKey])
      }
    })
  }
  emit('selectionChange', selectedData)
}

const clearSelection = () => {
  tableRef.value?.clearSelection()
}

// 分页
const handleCurrentChange = (page: number) => {
  searchForm.value.page = page
  getListData()
}

const handleSizeChange = (size: number) => {
  searchForm.value.size = size
  getListData()
}

// 添加自定义数据
const setListData = (list: any[]) => {
  listData.value = list
}

defineExpose({
  getListData,
  clearSelection,
  handleCurrentChange,
  selectedData,
  setListData
})
</script>

<style scoped lang="less">
.header {
  .handler {
    align-items: center;
  }
}

.footer {
  margin-top: 15px;

  .el-pagination {
    text-align: right;
  }
}

.el-table__row > td {
  border: none;
}

.el-table::before {
  height: 0px;
}

:deep(.el-dropdown) {
  display: flex;
  align-items: center;
  padding: 0;
  height: 23px;
  color: rgb(142, 155, 185);
  font-size: 12px;
  font-weight: bold;
  background: rgba(28, 155, 252, 0.02);
}
</style>
